home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1992 The Geometry Center; University of Minnesota
- 1300 South Second Street; Minneapolis, MN 55454, USA;
-
- This file is part of geomview/OOGL. geomview/OOGL is free software;
- you can redistribute it and/or modify it only under the terms given in
- the file COPYING, which you should have received along with this file.
- This and other related software may be obtained via anonymous ftp from
- geom.umn.edu; email: software@geom.umn.edu. */
-
- /* Authors: Charlie Gunn, Stuart Levy, Tamara Munzner, Mark Phillips */
-
- #include "mgP.h"
- #include "mgglP.h"
- #include "polylistP.h"
- #include <gl/gl.h>
-
- void mggl_polygon( int nv, HPoint3 *v, int nn, Point3 *n,
- int nc,ColorA *c );
- void mggl_mesh( int wrap,int nu,int nv,HPoint3 *p, Point3 *n,ColorA *c );
- void mggl_line( HPoint3 *p1, HPoint3 *p2 );
- void mggl_polyline( int nv, HPoint3 *verts, int nc, ColorA *colors, int wrap );
- void mggl_polylist( int np, Poly *p, int nv, Vertex *v,
- int plflags );
- void mggl_drawnormal(HPoint3 *p, Point3 *n);
-
- void mggl_closer();
- void mggl_farther();
-
- /*-----------------------------------------------------------------------
- * Function: mggl_polygon
- * Description: draw a polygon
- * Author: mbp, munzner
- * Date: Mon Jul 29 16:53:56 1991
- * Notes: See mg.doc.
- *
- * do later: Different shading cases separated into different
- * loops for speed.
- */
- void
- mggl_polygon(int nv, HPoint3 *V,
- int nn, Point3 *N,
- int nc, ColorA *C)
- {
- register int i;
- register HPoint3 *v;
- register Point3 *n;
- register ColorA *c;
- int cinc, ninc;
- int flag;
-
- flag = _mgc->astk->ap.flag;
- if ((_mgc->astk->mat.override & MTF_DIFFUSE) && !_mgc->astk->useshader)
- nc = 0;
- cinc = (nc > 1);
- ninc = (nn > 1);
- if(nc == 0)
- C = (ColorA*)&_mgc->astk->ap.mat->diffuse;
-
-
- /* reestablish correct drawing color if necessary */
-
- if (flag & APF_FACEDRAW) {
- lmcolor(_mgglc->lmcolor);
- bgnpolygon();
- if (nc <= 1)
- (*_mgglc->d4f)(&(_mgc->astk->ap.mat->diffuse));
- for (n = N, c = C, v = V, i = 0; i<nv; ++i, ++v) {
- if (nc) { (*_mgglc->d4f)(c); c += cinc; }
- if (nn) { (*_mgglc->n3f)(n,v); n += ninc; }
- v4f((float *)v);
- }
- endpolygon();
- }
-
- if( flag & (APF_EDGEDRAW|APF_NORMALDRAW) ) {
- if(_mgglc->znudge) mggl_closer();
- lmcolor(LMC_COLOR);
- if (flag & APF_EDGEDRAW) {
- c3f((float *)&_mgc->astk->ap.mat->edgecolor);
- bgnclosedline();
- for (v = V, i = 0; i<nv; ++i, ++v)
- v4f((float *)v);
- endclosedline();
- }
-
- if (flag & APF_NORMALDRAW) {
- c3f((float *)&_mgc->astk->ap.mat->normalcolor);
- for (n = N, v = V, i = 0; i<nv; ++i, ++v, n += ninc) {
- mggl_drawnormal(v, n);
- }
- }
- if(_mgglc->znudge) mggl_farther();
- }
- }
-
- void
- mggl_quads(int count, HPoint3 *V, Point3 *N, ColorA *C)
- {
- int i;
- register int k;
- register HPoint3 *v;
- register Point3 *n;
- register ColorA *c;
- ColorA cs[4];
- int flag;
-
- #define QUAD(stuff) { \
- register int k = 4; \
- bgnpolygon(); \
- do { stuff; } while(--k > 0); \
- endpolygon(); \
- }
-
- if(count <= 0)
- return;
- flag = _mgc->astk->ap.flag;
- if ((_mgc->astk->mat.override & MTF_DIFFUSE) && !_mgc->astk->useshader)
- C = NULL;
-
- /* reestablish correct drawing color if necessary */
-
- if (flag & APF_FACEDRAW) {
- lmcolor(_mgglc->lmcolor);
- i = count;
- v = V; c = C; n = N;
- if(c) {
- if(n) {
- do {
- QUAD( ((*_mgglc->d4f)(c++), (*_mgglc->n3f)(n++,v),
- v4f((float*)v++)) );
- } while(--i > 0);
- } else {
- /* Colors, no normals */
- do {
- QUAD( ((*_mgglc->d4f)(c++), v4f((float*)v++)) );
- } while(--i > 0);
- }
- } else {
- c = (ColorA*)&_mgc->astk->ap.mat->diffuse;
- if(n) {
- (*_mgglc->d4f)(c);
- do {
- QUAD( ((*_mgglc->n3f)(n++, v), v4f((float*)v++)) );
- } while(--i > 0);
- } else {
- (*_mgglc->d4f)(c);
- do {
- QUAD( (v4f((float*)v++)) );
- } while(--i > 0);
- }
- }
- }
-
- if( flag & (APF_EDGEDRAW|APF_NORMALDRAW) ) {
- if(_mgglc->znudge) mggl_closer();
- lmcolor(LMC_COLOR);
- if (flag & APF_EDGEDRAW) {
- c3f((float *)&_mgc->astk->ap.mat->edgecolor);
- i = count; v = V;
- do {
- register int k = 4;
- bgnclosedline();
- do { v4f((float *)v++); } while(--k > 0);
- endclosedline();
- } while(--i > 0);
- }
-
- if (flag & APF_NORMALDRAW && N) {
- c3f((float *)&_mgc->astk->ap.mat->normalcolor);
- i = count*4; v = V; n = N;
- do {
- mggl_drawnormal(v++, n++);
- } while(--i > 0);
- }
- if(_mgglc->znudge) mggl_farther();
- }
- }
-
-
- void mggl_line( HPoint3 *p1, HPoint3 *p2 )
- {
- bgnline();
- v4f((float *)p1);
- v4f((float *)p2);
- endline();
- }
-
- void mggl_point(register HPoint3 *v)
- {
- int i;
- HPoint3 a;
- register HPoint3 *p, *q;
- float vw;
-
- if(_mgc->astk->ap.linewidth > 1) {
-
- if(!(_mgc->has & HAS_POINT))
- mg_makepoint();
- /* Compute w component of point after projection to screen */
- vw = v->x * _mgc->O2S[0][3] + v->y * _mgc->O2S[1][3]
- + v->z * _mgc->O2S[2][3] + v->w * _mgc->O2S[3][3];
- if(vw <= 0) return;
-
- #define PUT(p) \
- a.x = v->x + p->x*vw; a.y = v->y + p->y*vw; \
- a.z = v->z + p->z*vw; a.w = v->w + p->w*vw; \
- v4f((float *)&a)
-
- p = VVEC(_mgc->point, HPoint3);
- q = p + VVCOUNT(_mgc->point);
-
- if(_mgglc->is_PI) {
- bgnpolygon();
- do {
- PUT(p);
- } while(++p < q);
- endpolygon();
- } else {
- bgntmesh();
- PUT(p);
- do {
- p++;
- PUT(p);
- if(p >= q) break;
- q--;
- PUT(q);
- } while(p < q);
- endtmesh();
- }
- } else {
- bgnpoint();
- v4f((float *)v);
- endpoint();
- }
- }
-
-
- void mggl_polyline( int nv, HPoint3 *v, int nc, ColorA *c, int wrapped )
- {
- int remain;
-
- /* note we don't reset to current material color because we could be
- * in the middle of a list of lines and should inherit the color from
- * the last color call.
- */
-
- if(!(wrapped & 2)) {
- /* First member of batch */
- if(_mgglc->znudge) mggl_closer();
- if(nc)
- lmcolor(LMC_COLOR);
- }
- if (nv == 1) {
- if(nc > 0) c4f((float *)c);
- mggl_point(v);
- }
- else if(nv > 0) {
- bgnline();
- if(wrapped & 1) {
- if(nc > 0) c4f((float *)(c + nc - 1));
- v4f((float *)(v + nv - 1));
- }
-
- for(;;) {
- remain = nv > 254 ? 254 : nv;
- nv -= remain;
- do {
- if(--nc >= 0) c4f((float *)c++);
- v4f((float *)v++);
- } while(--remain > 0);
- if(nv == 0)
- break;
- if(nc > 0) c4f((float *)c);
- v4f((float *)v);
- endline();
- bgnline();
- }
- endline();
- }
- if(!(wrapped & 4) && _mgglc->znudge) mggl_farther();
- }
-
-
- /*-----------------------------------------------------------------------
- * Function: mggl_polylist
- * Description: draws a Polylist: collection of Polys
- * Author: munzner
- * Date: Wed Oct 16 20:21:56 1991
- * Notes: see mg.doc
- */
- void mggl_polylist( int np, Poly *_p, int nv, Vertex *V, int plflags )
- {
- register int i,j;
- register Poly *p;
- register Vertex **v, *vp;
- register Point3 *n;
- struct mgastk *ma = _mgc->astk;
- void (*n3func)() = _mgglc->n3f;
- int flag,shading;
- int nonsurf = -1;
- flag = ma->ap.flag;
- shading = ma->ap.shading;
-
- switch(shading) {
- case APF_FLAT: plflags &= ~PL_HASVN; break;
- case APF_SMOOTH: plflags &= ~PL_HASPN; break;
- default: plflags &= ~(PL_HASVN|PL_HASPN); break;
- }
-
- if((_mgc->astk->mat.override & MTF_DIFFUSE) && !_mgc->astk->useshader)
- plflags &= ~(PL_HASVCOL | PL_HASPCOL);
-
- if (flag & APF_FACEDRAW) {
- lmcolor(_mgglc->lmcolor);
- /* reestablish correct drawing color if necessary*/
- if (!(plflags & (PL_HASPCOL | PL_HASVCOL)))
- (*_mgglc->d4f)(&(ma->ap.mat->diffuse));
-
- for (p = _p, i = 0; i < np; i++, p++) {
- if (plflags & PL_HASPCOL)
- (*_mgglc->d4f)(&p->pcol);
- if (plflags & PL_HASPN)
- (*n3func)(&p->pn, &(*p->v)->pt);
- v = p->v;
- if((j = p->n_vertices) <= 2) {
- nonsurf = i;
- } else {
- bgnpolygon();
- do {
- if (plflags & PL_HASVCOL) (*_mgglc->d4f)(&(*v)->vcol);
- if (plflags & PL_HASVN) (*n3func)(&(*v)->vn, &(*v)->pt);
- v4f((float *)&(*v)->pt);
- v++;
- } while(--j > 0);
- endpolygon();
- }
- }
- }
-
- if (flag & (APF_EDGEDRAW|APF_NORMALDRAW) || nonsurf >= 0) {
- if(_mgglc->znudge) mggl_closer();
- lmcolor(LMC_COLOR);
-
- if (flag & APF_EDGEDRAW) {
- c3f((float *)&_mgc->astk->ap.mat->edgecolor);
- for (p = _p, i = 0; i < np; i++, p++) {
- bgnclosedline();
- for (j=0, v=p->v; j < p->n_vertices; j++, v++) {
- v4f((float *)&(*v)->pt);
- }
- endclosedline();
- }
- }
-
- if (flag & APF_NORMALDRAW) {
- c3f((float *)&_mgc->astk->ap.mat->normalcolor);
- if (plflags & PL_HASPN) {
- for (p = _p, i = 0; i < np; i++, p++) {
- for (j=0, v=p->v; j < p->n_vertices; j++, v++)
- mggl_drawnormal(&(*v)->pt, &p->pn);
- }
- } else if (plflags & PL_HASVN) {
- for (vp = V, i = 0; i < nv; i++, vp++) {
- mggl_drawnormal(&vp->pt, &vp->vn);
- }
- }
- }
-
-
- if (nonsurf >= 0) {
- /* reestablish correct drawing color if necessary*/
- if (!(plflags & (PL_HASPCOL | PL_HASVCOL)))
- (*_mgglc->d4f)(&(ma->ap.mat->diffuse));
-
- for(p = _p, i = 0; i <= nonsurf; p++, i++) {
- if (plflags & PL_HASPCOL)
- (*_mgglc->d4f)(&p->pcol);
- v = p->v;
- switch(j = p->n_vertices) {
- case 1:
- if(plflags & PL_HASVCOL) c4f((float *)&(*v)->vcol);
- mggl_point(&(*v)->pt);
- break;
- case 2:
- bgnline();
- do {
- if(plflags & PL_HASVCOL) c4f((float *)&(*v)->vcol);
- v4f((float *)&(*v)->pt);
- v++;
- } while(--j > 0);
- endline();
- break;
- }
- }
- }
- if(_mgglc->znudge) mggl_farther();
- }
- }
-
- /*
- * Z-shift routines: for moving edges closer than faces, etc.
- */
- mggl_init_zrange()
- {
- register struct mgglcontext *gl = _mgglc;
-
- gl->znudge = _mgc->zfnudge * (gl->zmax - gl->zmin);
-
- gl->znear = gl->zmin + abs(gl->znudge * MAXZNUDGE);
- gl->zfar = gl->zmax - abs(gl->znudge * MAXZNUDGE);
- lsetdepth(gl->znear, gl->zfar);
- }
-
- void
- mggl_closer()
- {
- lsetdepth( _mgglc->znear -= _mgglc->znudge, _mgglc->zfar -= _mgglc->znudge );
- }
- void
- mggl_farther()
- {
- lsetdepth( _mgglc->znear += _mgglc->znudge, _mgglc->zfar += _mgglc->znudge );
- }
-
- /* There is a basic problem now with 4-d points and 3-d normal vectors.
- For now, we'll just ignore the 4-th coordinate of the point when
- computing the tip of the normal vector. This will work OK with all
- existing models, but for genuine 4-d points it won't work. But,
- come to think of it, what is the correct interpretation of the
- normal vector when the points live in 4-d?
- */
- void
- mggl_drawnormal(register HPoint3 *p, Point3 *n)
- {
- Point3 end, tp;
- float scale;
-
- if (p->w <= 0.0) return;
- if(p->w != 1) {
- HPt3ToPt3(p, &tp);
- p = (HPoint3 *)&tp;
- }
-
- scale = _mgc->astk->ap.nscale;
- if(_mgc->astk->ap.flag & APF_EVERT) {
- register Point3 *cp = &_mgc->cpos;
- if(!(_mgc->has & HAS_CPOS))
- mg_findcam();
- if((p->x-cp->x) * n->x + (p->y-cp->y) * n->y + (p->z-cp->z) * n->z > 0)
- scale = -scale;
- }
-
- end.x = p->x + scale*n->x;
- end.y = p->y + scale*n->y;
- end.z = p->z + scale*n->z;
- bgnline();
- v3f((float *)p);
- v3f((float *)&end);
- endline();
- }
-